# -*- coding: utf-8 -*-
#
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

"""
语句发射器
处理各种语句节点的代码生成。
"""

from typing import List, Union
from ...ir import IRNode, IRFunctionNode
from ...ir.statements import (
    IRAssign,
    IRAugAssign,
    IRReturn,
    IRBreak,
    IRContinue,
    IRExprStmt,
    IRIf,
    IRForRange,
    IRForEach,
    IRWhile,
    IRGlobal,
    IRNonlocal,
    IRDelete,
    IRPass,
    IRRaise,
    IRTryExcept,
)
from ...symbol_meta import TypeInfo, TypeKind
from ...ir.expressions import IRName, IRAttribute, IRCall
from ...ir.statements.base import IRStmtBlock
from ...ir.expressions.access import IRSubscript
from ..core.emitter import NodeTypeEmitter, EmitResult
from ..core.context import CodeGenContext
from ..core.generator import get_global_generator
from ..finally_context import FinallyContext
from ...ir.expressions import IRUnaryOp, IRCompare, IRBoolOp
from mcpy.symbol_meta import SymbolKind
from .exception_constructor_emitter import is_exception_type
from ...type_system import get_cpp_type


class StatementEmitter(NodeTypeEmitter):
    """
    语句发射器

    处理各种语句节点的代码生成。
    """

    def __init__(self):
        super().__init__(
            [
                IRAssign,
                IRAugAssign,
                IRReturn,
                IRBreak,
                IRContinue,
                IRExprStmt,
                IRIf,
                IRForRange,
                IRForEach,
                IRWhile,
                IRGlobal,
                IRNonlocal,
                IRDelete,
                IRPass,
                IRRaise,
                IRTryExcept,
                IRFunctionNode,  # 嵌套函数
            ]
        )

    def _get_next_no_exception_var_name(self, current_node: IRNode) -> str:
        """生成作用域内唯一的异常标志变量名

        Args:
            current_node: 当前 IR 节点（try/except 语句）

        Returns:
            唯一的变量名，基于所在函数作用域生成
        """
        # 查找所在的函数作用域
        scope = current_node.get_parent_scope()
        if scope is None:
            # 如果没有父作用域（不太可能），使用默认名称
            return "__no_exception"

        counter_key = "_no_exception_counter"
        counter = scope.get_extension_param(counter_key, 0)
        counter += 1
        scope.set_extension_param(counter_key, counter, replace_existing=True)

        # 第一次使用简单名称，之后加上计数器后缀
        if counter == 1:
            return "__no_exception"
        return f"__no_exception_{counter}"

    def emit(self, node: IRNode, context: CodeGenContext) -> EmitResult:
        """生成语句代码"""
        if isinstance(node, IRAssign):
            return self._emit_assign(node, context)
        elif isinstance(node, IRAugAssign):
            return self._emit_aug_assign(node, context)
        elif isinstance(node, IRReturn):
            return self._emit_return(node, context)
        elif isinstance(node, IRBreak):
            return self._emit_break(node, context)
        elif isinstance(node, IRContinue):
            return self._emit_continue(node, context)
        elif isinstance(node, IRExprStmt):
            return self._emit_expr_stmt(node, context)
        elif isinstance(node, IRIf):
            return self._emit_if(node, context)
        elif isinstance(node, (IRForRange, IRForEach)):
            return self._emit_for(node, context)
        elif isinstance(node, IRWhile):
            return self._emit_while(node, context)
        elif isinstance(node, IRGlobal):
            return self._emit_global(node, context)
        elif isinstance(node, IRNonlocal):
            return self._emit_nonlocal(node, context)
        elif isinstance(node, IRDelete):
            return self._emit_delete(node, context)
        elif isinstance(node, IRPass):
            return self._emit_pass(node, context)
        elif isinstance(node, IRRaise):
            return self._emit_raise(node, context)
        elif isinstance(node, IRTryExcept):
            return self._emit_try_except(node, context)

        elif isinstance(node, IRFunctionNode):
            return self._emit_nested_function(node, context)

        return EmitResult(
            code=f"/* Unknown statement type: {type(node).__name__} */", precedence=0
        )

    def _emit_assign(self, node: IRAssign, context: CodeGenContext) -> EmitResult:
        """生成赋值语句"""

        generator = get_global_generator()

        # 生成目标变量 - 使用新的 IR 节点机制
        target_expr = node.get_target_expr()
        if not target_expr:
            return EmitResult(code="/* No target expression */", precedence=0)

        # 获取目标名称和代码
        if isinstance(target_expr, IRName):
            target_code = target_expr.id
        elif isinstance(target_expr, IRAttribute):
            if isinstance(target_expr.value, IRName) and target_expr.value.id == "self":
                target_code = f"this->{target_expr.attr}"
            else:
                target_code = f"{target_expr.value}.{target_expr.attr}"
        else:
            target_code = str(target_expr)

        # 生成值表达式
        value_context = context.create_child_context(in_assignment=True)
        value_code = generator.generate_expression(node.value, value_context)

        # 获取目标类型（用于类型转换）
        target_cpp_type = None
        if node.annotation:
            # 从类型注解获取目标类型
            from mcpy.type_system import parse_type_with_context, get_cpp_type

            target_type_info = parse_type_with_context(node.annotation, node=node)
            if target_type_info:
                target_cpp_type = get_cpp_type(target_type_info, node)

        # 应用类型转换（如果需要）
        if target_cpp_type:
            from mcpy.codegen.utils.type_conversion import apply_variant_conversion

            value_cpp_type = context.get_cpp_type(node.value)
            original_value_code = value_code
            value_code = apply_variant_conversion(
                value_code, value_cpp_type, target_cpp_type
            )
            if value_code != original_value_code:
                context.require_include("mcpy/builtins.h")

        # 使用 Pass 阶段分析的结果
        # 处理多目标赋值的情况
        if node.has_extension_param("target_declarations"):
            # 多目标赋值，需要检查当前目标是否是声明
            target_declarations = node.get_extension_param("target_declarations", {})
            is_declaration = target_declarations.get(target_code, False)
        else:
            # 单目标赋值
            is_declaration = node.get_extension_param("is_variable_declaration", False)

        # 属性赋值（this->x）不需要声明
        is_attribute_assignment = target_code.startswith("this->")

        if is_declaration and not is_attribute_assignment:
            # 检查是否有显式类型注解
            if node.annotation:
                # 使用显式类型
                code = f"{node.annotation} {target_code} = {value_code};"
            else:
                # 统一使用 auto 声明，避免占位类型导致编译错误
                code = f"auto {target_code} = {value_code};"
        else:
            # 已存在的变量赋值或属性赋值
            code = f"{target_code} = {value_code};"

        return EmitResult(code=code, precedence=0)

    def _emit_aug_assign(
        self, node: IRAugAssign, context: CodeGenContext
    ) -> EmitResult:
        """生成增强赋值语句"""

        generator = get_global_generator()

        # 生成目标变量 - 处理特殊情况
        target_code = node.target  # IRAugAssign.target 是字符串

        # 特殊处理：self.x -> this->x
        if target_code.startswith("self."):
            target_code = target_code.replace("self.", "this->", 1)

        # 生成值表达式
        value_context = context.create_child_context(in_assignment=True)
        value_code = generator.generate_expression(node.value, value_context)

        # 检查是否需要类型转换（Any -> 强类型）
        # 如果右操作数是 Any 类型，需要进行类型转换
        value_code = self._apply_aug_assign_type_conversion(value_code, node, context)

        # 生成增强赋值操作符
        # 注意：IRAugAssign.op 已经是操作符字符串（如 "+"），我们需要添加 "="
        code = f"{target_code} {node.op}= {value_code};"

        return EmitResult(code=code, precedence=0)

    def _apply_aug_assign_type_conversion(
        self, value_code: str, node: IRAugAssign, context: CodeGenContext
    ) -> str:
        """为增强赋值运算符应用类型转换

        如果右操作数是 Any 类型，需要使用 mcpy::cast 进行类型转换，
        因为 C++ 不支持 int += mc::variant 这样的增强赋值运算符。

        Args:
            value_code: 右操作数的生成代码
            node: 增强赋值节点
            context: 代码生成上下文

        Returns:
            str: 可能经过类型转换的代码
        """
        from mcpy.codegen.utils.type_conversion import generate_variant_cast

        # 检查右操作数是否是 Any 类型
        if not hasattr(node, "value") or not node.value:
            return value_code

        value_type: TypeInfo = node.value.get_extension_param("inferred_type")
        if not value_type or value_type.kind != TypeKind.ANY:
            return value_code

        # 右操作数是 Any，需要获取目标变量的类型进行转换
        # 通过符号表查找目标变量的类型
        if not context.current_node:
            return value_code

        target_symbol = context.current_node.lookup_symbol(node.target)
        if (
            not target_symbol
            or not target_symbol.type_info
            or target_symbol.type_info.kind == TypeKind.ANY
        ):
            # 目标变量类型未知或为 Any 类型，不需要转换
            return value_code

        target_cpp_type = get_cpp_type(target_symbol.type_info, context.current_node)
        if not target_cpp_type:
            return value_code

        # 应用类型转换
        context.require_include("mcpy/builtins.h")
        return generate_variant_cast(value_code, target_cpp_type)

    def _emit_return(self, node: IRReturn, context: CodeGenContext) -> EmitResult:
        """生成return语句

        支持 variant 到强类型的自动转换：
        - 获取函数返回类型
        - 如果返回值是 mc::variant，且函数返回类型是强类型
        - 自动插入 cast 转换

        在 finally 块中：
        - 设置 __has_return = true
        - 如果有返回值，保存到 __return_value
        - 跳转到 finally 标签
        """
        # 从栈获取当前 finally 上下文
        finally_ctx = context.finally_stack.current()

        if finally_ctx:
            # 在 finally 块中，生成 goto 代码
            lines = []
            lines.append(f"{finally_ctx.has_return_var} = true;")

            if node.expr:
                generator = get_global_generator()
                try:
                    value_code = generator.generate_expression(node.expr, context)

                    # 尝试应用类型转换
                    value_code = self._apply_return_type_conversion(
                        value_code, node.expr, context
                    )

                    if finally_ctx.return_type != "void":
                        lines.append(f"{finally_ctx.return_value_var} = {value_code};")
                except Exception as e:
                    import traceback

                    traceback.print_exc()
                    raise

            lines.append(f"goto {finally_ctx.label};")
            code = "\n".join(lines)
        else:
            # 正常 return
            if node.expr:
                generator = get_global_generator()
                try:
                    value_code = generator.generate_expression(node.expr, context)

                    # 尝试应用类型转换
                    value_code = self._apply_return_type_conversion(
                        value_code, node.expr, context
                    )

                    code = f"return {value_code};"
                except Exception as e:
                    import traceback

                    traceback.print_exc()
                    raise
            else:
                code = "return;"

        return EmitResult(code=code, precedence=0)

    def _apply_return_type_conversion(
        self, value_code: str, value_node: IRNode, context: CodeGenContext
    ) -> str:
        """应用返回值类型转换（如果需要）

        Args:
            value_code: 返回值表达式代码
            value_node: 返回值 IR 节点
            context: 代码生成上下文

        Returns:
            str: 可能经过转换的代码
        """
        from mcpy.codegen.utils.type_conversion import apply_variant_conversion
        from mcpy.ir.declarations.function import IRFunctionNode

        # 检查是否需要包装为mc::result（async函数）
        current_func = context.current_function
        if current_func and context.ir_module:
            # 查找当前函数节点
            func_node = None

            def find_func(node):
                nonlocal func_node
                if isinstance(node, IRFunctionNode) and node.name == current_func:
                    func_node = node
                    return
                for child in node.get_child_nodes():
                    find_func(child)

            find_func(context.ir_module)

            # 如果是async函数，需要包装返回值
            if func_node and func_node.get_extension_param("wrap_return_as_result"):
                cpp_return_type = func_node.get_extension_param("cpp_return_type")
                if cpp_return_type and cpp_return_type.startswith("mc::result<"):
                    # 包装返回值为mc::result
                    context.require_include("mc/result.h")
                    return f"{cpp_return_type}({value_code})"

        # 获取函数返回类型
        function_return_type = context.get_function_return_type()
        if not function_return_type:
            return value_code

        # 获取返回值类型
        value_cpp_type = context.get_cpp_type(value_node)

        # 应用 variant 转换
        result = apply_variant_conversion(
            value_code, value_cpp_type, function_return_type
        )
        if result != value_code:
            # 需要 mcpy 辅助函数
            context.require_include("mcpy/builtins.h")
        return result

    def _emit_break(self, node: IRBreak, context: CodeGenContext) -> EmitResult:
        """生成break语句

        在 finally 块中：
        - 设置 __should_break = true
        - 跳转到 finally 标签

        在异步循环中（co_yield 块内）：
        - 使用 co_break 跳出用户循环
        """
        # 从栈获取当前 finally 上下文
        finally_ctx = context.finally_stack.current()

        if finally_ctx:
            # 在 finally 块中，生成 goto 代码
            lines = []
            lines.append(f"{finally_ctx.should_break_var} = true;")
            lines.append(f"goto {finally_ctx.label};")
            code = "\n".join(lines)
        else:
            # 检查是否在 co_yield 块中
            in_co_yield = context.get_extension_param("in_co_yield_block", False)
            if in_co_yield:
                # 在 co_yield 块中，使用 co_break
                code = "co_break;"
            else:
                # 普通的 break
                code = "break;"

        return EmitResult(code=code, precedence=0)

    def _emit_continue(self, node: IRContinue, context: CodeGenContext) -> EmitResult:
        """生成continue语句

        在 finally 块中：
        - 设置 __should_continue = true
        - 跳转到 finally 标签

        在异步循环中（co_yield 块内）：
        - 使用 co_continue 跳转到循环继续位置
        """
        # 从栈获取当前 finally 上下文
        finally_ctx = context.finally_stack.current()

        if finally_ctx:
            # 在 finally 块中，生成 goto 代码
            lines = []
            lines.append(f"{finally_ctx.should_continue_var} = true;")
            lines.append(f"goto {finally_ctx.label};")
            code = "\n".join(lines)
        else:
            # 检查是否在 co_yield 块中
            in_co_yield = context.get_extension_param("in_co_yield_block", False)
            if in_co_yield:
                # 在 co_yield 块中，使用 co_continue
                code = "co_continue;"
            else:
                # 普通的 continue
                code = "continue;"

        return EmitResult(code=code, precedence=0)

    def _emit_expr_stmt(self, node: IRExprStmt, context: CodeGenContext) -> EmitResult:
        """生成表达式语句"""

        generator = get_global_generator()
        expr_code = generator.generate_expression(node.expr, context)
        code = f"{expr_code};"

        return EmitResult(code=code, precedence=0)

    def _emit_if(self, node: IRIf, context: CodeGenContext) -> EmitResult:
        """生成if语句"""

        generator = get_global_generator()
        lines = []

        # 生成条件表达式，使用合适的优先级避免不必要的括号
        # 比较操作符优先级是11，我们使用12避免为简单比较添加括号
        test_context = context.with_precedence(12)
        test_code = generator.generate_expression(node.test, test_context)

        # 检查条件表达式是否需要隐式布尔转换
        # 如果条件表达式的类型有 __bool__ 方法，调用它
        test_code = self._apply_implicit_bool_conversion(node.test, test_code, context)
        lines.append(f"if ({test_code}) {{")

        # 生成if体
        if node.then_body:
            # 生成语句列表，直接使用父上下文共享变量声明状态
            statements = self._get_statements(node.then_body)
            for stmt in statements:
                stmt_context = context.create_child_context(current_node=stmt)
                stmt_code = generator.generate_statement(stmt, stmt_context)
                if stmt_code:
                    lines.append(f"    {stmt_code}")

        # 生成else分支
        if node.else_body:
            # 检查是否是elif模式（else分支只包含一个if语句）
            statements = self._get_statements(node.else_body)
            if len(statements) == 1 and isinstance(statements[0], IRIf):
                # 这是elif，生成else if
                elif_node = statements[0]
                elif_test_context = context.with_precedence(12)
                elif_test_code = generator.generate_expression(
                    elif_node.test, elif_test_context
                )
                lines.append(f"}} else if ({elif_test_code}) {{")

                # 生成elif的then分支
                if elif_node.then_body:
                    elif_statements = self._get_statements(elif_node.then_body)
                    for stmt in elif_statements:
                        stmt_context = context.create_child_context(current_node=stmt)
                        stmt_code = generator.generate_statement(stmt, stmt_context)
                        if stmt_code:
                            lines.append(f"    {stmt_code}")

                # 递归处理elif的else分支
                if elif_node.else_body:
                    # 创建一个临时的IRIf节点来处理剩余的else分支
                    temp_if = IRIf()
                    temp_if.else_body = elif_node.else_body
                    temp_result = self._emit_if(temp_if, context)
                    # 提取else部分并添加到当前lines
                    temp_lines = temp_result.code.split("\n")
                    for line in temp_lines:
                        if line.strip() and not line.strip().startswith("if"):
                            lines.append(line)
                    return EmitResult(code="\n".join(lines), precedence=0)
            else:
                # 普通的else分支
                lines.append("} else {")
                for stmt in statements:
                    stmt_context = context.create_child_context(current_node=stmt)
                    stmt_code = generator.generate_statement(stmt, stmt_context)
                    if stmt_code:
                        lines.append(f"    {stmt_code}")

        lines.append("}")
        code = "\n".join(lines)

        return EmitResult(code=code, precedence=0)

    def _emit_for(
        self, node: Union[IRForRange, IRForEach], context: CodeGenContext
    ) -> EmitResult:
        """生成for循环"""
        if isinstance(node, IRForRange):
            return self._emit_for_range(node, context)
        elif isinstance(node, IRForEach):
            return self._emit_for_each(node, context)
        else:
            return EmitResult(code="/* Unknown for loop type */", precedence=0)

    def _emit_for_range(self, node: IRForRange, context: CodeGenContext) -> EmitResult:
        """生成range for循环"""

        generator = get_global_generator()
        lines = []

        # 生成循环变量、起始值、结束值
        start_code = generator.generate_expression(node.start, context)
        end_code = generator.generate_expression(node.end, context)

        # 检查步长
        step_code = generator.generate_expression(node.step, context)

        # 获取循环变量的类型
        loop_var_type = self._get_loop_var_cpp_type(node, context)

        # 生成for循环头
        if step_code == "1":
            # 标准递增循环: for (int i = 0; i < n; ++i)
            var_name = node.var.id
            lines.append(
                f"for ({loop_var_type} {var_name} = {start_code}; {var_name} < {end_code}; ++{var_name}) {{"
            )
        else:
            # 自定义步长: for (int i = start; i < end; i += step)
            var_name = node.var.id
            lines.append(
                f"for ({loop_var_type} {var_name} = {start_code}; {var_name} < {end_code}; {var_name} += {step_code}) {{"
            )

        # 生成循环体
        if node.body:
            statements = self._get_statements(node.body)
            for stmt in statements:
                stmt_context = context.create_child_context(current_node=stmt)
                stmt_code = generator.generate_statement(stmt, stmt_context)
                if stmt_code:
                    lines.append(f"    {stmt_code}")

        lines.append("}")
        code = "\n".join(lines)

        return EmitResult(code=code, precedence=0)

    def _get_loop_var_cpp_type(self, node, context: CodeGenContext) -> str:
        """获取循环变量的 C++ 类型"""
        return context.get_loop_var_cpp_type(node, node.var.id)

    def _emit_for_each(self, node: IRForEach, context: CodeGenContext) -> EmitResult:
        """生成for-each循环"""

        generator = get_global_generator()
        lines = []

        # 生成迭代表达式
        iter_code = generator.generate_expression(node.iter_expr, context)

        # 检查是否需要类型转换（弱类型容器 -> 强类型循环变量）
        needs_type_conversion = False
        loop_var_name = None
        loop_var_cpp_type = None

        if isinstance(node.var, IRName):
            loop_var_name = node.var.id
            # 获取循环变量的 Python 类型推导出的 C++ 类型
            loop_var_cpp_type = self._get_loop_var_cpp_type(node, context)

            # 获取容器元素类型
            iter_cpp_type = context.get_cpp_type(node.iter_expr)

            # 判断是否需要转换：容器是弱类型（variant_set, mc::variants）
            if iter_cpp_type and (
                "variant_set" in iter_cpp_type or "mc::variants" in iter_cpp_type
            ):
                if loop_var_cpp_type and "variant" not in loop_var_cpp_type.lower():
                    needs_type_conversion = True

        # 检查是否是元组解包
        if isinstance(node.var, IRName):
            if needs_type_conversion:
                # 使用临时变量名迭代，然后在循环体内转换
                temp_var = f"__iter_{loop_var_name}"
                lines.append(f"for (const auto& {temp_var} : {iter_code}) {{")
                # 在循环体开始处添加类型转换
                lines.append(
                    f"    {loop_var_cpp_type} {loop_var_name} = mcpy::cast<{loop_var_cpp_type}>({temp_var});"
                )
                context.require_include("mcpy/builtins.h")
            else:
                # 单变量：for x in xs
                lines.append(f"for (const auto& {node.var.id} : {iter_code}) {{")
        else:
            # 元组解包：for x, y in pairs
            # 使用结构化绑定：for (const auto& [x, y] : pairs)
            var_names = self._extract_var_names_from_target(node.var)
            var_list = ", ".join(var_names)
            lines.append(f"for (const auto& [{var_list}] : {iter_code}) {{")

        # 生成循环体
        if node.body:
            statements = self._get_statements(node.body)
            for stmt in statements:
                stmt_context = context.create_child_context(current_node=stmt)
                stmt_code = generator.generate_statement(stmt, stmt_context)
                if stmt_code:
                    lines.append(f"    {stmt_code}")

        lines.append("}")
        code = "\n".join(lines)

        return EmitResult(code=code, precedence=0)

    def _extract_var_names_from_target(self, target: IRNode) -> list[str]:
        """从目标节点中提取所有变量名

        Args:
            target: 目标节点（可能是 IRName、IRTuple 或 IRList）

        Returns:
            变量名列表
        """

        if isinstance(target, IRName):
            return [target.id]
        elif hasattr(target, "elements"):
            # IRTuple 或 IRList
            result = []
            for element in getattr(target, "elements"):
                result.extend(self._extract_var_names_from_target(element))
            return result
        return []

    def _get_statements(
        self, body: Union[IRNode, IRStmtBlock, List[IRNode]]
    ) -> List[IRNode]:
        """获取语句列表

        如果body是IRStmtBlock，返回其statements属性；
        如果body是列表，直接返回；
        否则将body作为单元素列表返回。

        Args:
            body: 语句块或单个语句

        Returns:
            List[IRNode]: 语句列表
        """
        if isinstance(body, IRStmtBlock):
            return body.statements
        elif isinstance(body, list):
            return body
        else:
            return [body]

    def _emit_while(self, node: IRWhile, context: CodeGenContext) -> EmitResult:
        """生成while循环"""

        generator = get_global_generator()
        lines = []

        # 生成条件表达式
        test_code = generator.generate_expression(node.test, context)
        lines.append(f"while ({test_code}) {{")

        # 生成循环体
        if node.body:
            # 生成语句列表
            statements = self._get_statements(node.body)
            for stmt in statements:
                stmt_context = context.create_child_context(current_node=stmt)
                stmt_code = generator.generate_statement(stmt, stmt_context)
                if stmt_code:
                    lines.append(f"    {stmt_code}")

        lines.append("}")
        code = "\n".join(lines)

        return EmitResult(code=code, precedence=0)

    def _emit_global(self, node: IRGlobal, context: CodeGenContext) -> EmitResult:
        """生成 global 语句代码

        在 C++ 中，global 语句不需要生成代码，因为全局变量的作用域
        在编译时就已经确定了。
        """
        # global 语句在 C++ 中不需要生成代码
        return EmitResult(code="", precedence=0, metadata={"success": True})

    def _emit_pass(self, node: IRPass, context: CodeGenContext) -> EmitResult:
        """生成 pass 语句代码

        pass 语句在 C++ 中不需要生成任何代码，
        空的循环体或条件体会自动生成空大括号 {}
        """
        # pass 语句不生成任何代码
        return EmitResult(code="", precedence=0, metadata={"success": True})

    def _emit_nonlocal(self, node: IRNonlocal, context: CodeGenContext) -> EmitResult:
        """生成 nonlocal 语句代码

        在 C++ 中，nonlocal 语句不需要生成代码，因为变量的作用域
        在编译时就已经确定了。
        """
        # nonlocal 语句在 C++ 中不需要生成代码
        return EmitResult(code="", precedence=0, metadata={"success": True})

    def _emit_delete(self, node: IRDelete, context: CodeGenContext) -> EmitResult:
        """生成 delete 语句代码

        通过符号体系查找 __delitem__ 方法，支持 builtin 类型、用户自定义类和 stub

        delete 语句用于删除容器元素，例如：
        del list[0]  ->  使用 __delitem__ 方法模板
        """

        generator = get_global_generator()

        lines = []
        for target in node.targets:
            # 对于下标访问表达式（list[index]），查找 __delitem__ 方法
            if hasattr(target, "node_type") and target.node_type == "subscript":

                # 类型转换确保 Pyright 正确识别属性
                subscript_target = target if isinstance(target, IRSubscript) else None
                if not subscript_target:
                    return EmitResult(
                        code="/* Invalid subscript target */", precedence=0
                    )

                # 获取对象代码
                obj_code = generator.generate_expression(
                    subscript_target.value, context
                )

                # 检查是否是切片删除
                slice_delete_code = self._try_emit_slice_delete(
                    subscript_target, obj_code, context
                )
                if slice_delete_code:
                    lines.append(slice_delete_code)
                    continue

                # 不是切片，尝试使用 __delitem__ 方法
                delitem_code = self._try_emit_delitem_method(target, obj_code, context)

                if delitem_code:
                    lines.append(f"{delitem_code};")
                else:
                    # 没有找到 __delitem__ 配置，生成索引代码用于错误提示
                    slice_code = generator.generate_expression(
                        subscript_target.slice, context
                    )
                    lines.append(
                        f"/* No __delitem__ method found for {obj_code}[{slice_code}] */"
                    )
            else:
                # 对于普通变量删除，在 C++ 中不需要生成代码
                # 因为 C++ 使用 RAII 自动管理内存
                pass

        final_code = "\n".join(lines) if lines else ""
        return EmitResult(code=final_code, precedence=0)

    def _try_emit_slice_delete(
        self, target_expr: IRSubscript, obj_code: str, context: CodeGenContext
    ) -> str | None:
        """尝试生成切片删除代码

        Args:
            target_expr: 目标下标表达式
            obj_code: 对象表达式代码
            context: 代码生成上下文

        Returns:
            str | None: 生成的切片删除代码，如果不是切片则返回 None
        """
        from ...ir.expressions.access import IRSlice

        # 检查是否是切片
        if not isinstance(target_expr.slice, IRSlice):
            return None

        slice_info = target_expr.slice

        generator = get_global_generator()

        # 提取 start, stop, step
        start_code = "INT64_MIN"
        stop_code = "INT64_MIN"
        step_code = "1"

        if slice_info.lower is not None:
            start_code = generator.generate_expression(slice_info.lower, context)

        if slice_info.upper is not None:
            stop_code = generator.generate_expression(slice_info.upper, context)

        if slice_info.step is not None:
            step_code = generator.generate_expression(slice_info.step, context)

        # 添加必要的包含文件
        context.require_include("mcpy/builtins.h")
        context.require_include("<cstdint>")

        # 生成切片删除调用代码
        code = f"mcpy::list_slice_delete({obj_code}, {start_code}, {stop_code}, {step_code});"

        return code

    def _try_emit_delitem_method(
        self, node, obj_code: str, context: CodeGenContext
    ) -> str | None:
        """尝试使用类型符号的 __delitem__ 方法生成代码

        通过符号体系查找 __delitem__ 方法，支持 builtin 类型、用户自定义类和 stub

        Args:
            node: 下标访问节点
            obj_code: 对象表达式代码
            context: 代码生成上下文

        Returns:
            str | None: 生成的代码，如果无法使用配置则返回 None
        """
        generator = get_global_generator()
        # 从推断类型获取 TypeInfo
        type_info = node.value.get_extension_param("inferred_type")
        if not type_info:
            return None

        # 获取索引的类型信息用于方法重载匹配
        index_type = node.slice.get_extension_param("inferred_type")
        args_types = [index_type] if index_type else []

        # 查找 __delitem__ 方法符号
        # 使用 IRNode.lookup_symbol（内部已经处理内置类型和用户自定义类）
        method_symbol = None
        if context.current_node:
            method_symbol = context.current_node.lookup_symbol(
                "__delitem__",
                owner_type=type_info,
                func_args=args_types,
            )

        if not method_symbol:
            return None

        # 获取匹配的签名
        matching_signature = method_symbol.find_matching_signature(
            [type_info] + args_types
        )
        if not matching_signature:
            # 如果没有找到匹配的签名，使用第一个签名
            if method_symbol.signatures:
                matching_signature = method_symbol.signatures[0]
            else:
                return None

        # 获取模板
        template = matching_signature.emit_template
        if not template:
            return None

        # 添加必要的包含文件
        includes = getattr(matching_signature, "includes", [])
        for include in includes:
            context.require_include(include)

        # 获取索引参数的期望类型
        expected_index_cpp_type = self._get_index_expected_type(
            method_symbol, matching_signature, node, context
        )

        # 生成索引表达式（传递期望类型）
        index_context = context.create_child_context(
            expected_cpp_type=expected_index_cpp_type
        )
        index_code = generator.generate_expression(
            node.slice, index_context, parent_precedence=100
        )

        # 应用类型转换（如果需要：mc::variant -> int）
        if expected_index_cpp_type:
            actual_index_cpp_type = context.get_cpp_type(node.slice)
            index_code = self._apply_index_type_conversion(
                index_code, actual_index_cpp_type, expected_index_cpp_type, context
            )

        # 替换模板占位符
        code = template.replace("{self}", obj_code).replace("{index}", index_code)

        return code

    def _get_index_expected_type(
        self, method_symbol, signature, node, context: CodeGenContext
    ) -> str | None:
        """从方法符号的 TypeInfo 中获取索引参数的期望 C++ 类型"""
        if method_symbol and method_symbol.type_info and method_symbol.type_info.args:
            from mcpy.type_system import get_cpp_type

            # __delitem__ 的参数：[self, index]
            if len(method_symbol.type_info.args) >= 2:
                index_param_type_info = method_symbol.type_info.args[1]
                try:
                    cpp_type = get_cpp_type(index_param_type_info, node)
                    return cpp_type
                except:
                    pass

        return None

    def _apply_index_type_conversion(
        self,
        value_code: str,
        value_cpp_type: str | None,
        target_cpp_type: str,
        context: CodeGenContext,
    ) -> str:
        """应用索引类型转换"""
        from mcpy.codegen.utils.type_conversion import apply_variant_conversion

        result = apply_variant_conversion(value_code, value_cpp_type, target_cpp_type)
        if result != value_code:
            context.require_include("mcpy/builtins.h")
        return result

    def _apply_implicit_bool_conversion(
        self, test_node: IRNode, test_code: str, context: CodeGenContext
    ) -> str:
        """对条件表达式应用隐式布尔转换

        Args:
            test_node: 条件表达式的 IR 节点
            test_code: 已生成的条件表达式代码
            context: 代码生成上下文

        Returns:
            可能经过布尔转换的代码
        """

        # 如果已经是布尔操作、比较操作或一元操作（包括 not），不需要转换
        if isinstance(test_node, (IRUnaryOp, IRCompare, IRBoolOp)):
            return test_code

        # 获取条件表达式的类型
        type_info = test_node.get_extension_param("inferred_type")
        if not type_info:
            return test_code

        # 查找 __bool__ 方法符号
        # 注意：__bool__ 方法不需要额外参数（除了 self）
        if not context.current_node:
            return test_code

        method_symbol = context.current_node.lookup_symbol(
            "__bool__",
            owner_type=type_info,
            func_args=[],
        )

        if not method_symbol:
            return test_code

        # 获取匹配的签名
        matching_signature = method_symbol.find_matching_signature([type_info])
        if not matching_signature:
            if method_symbol.signatures:
                matching_signature = method_symbol.signatures[0]
            else:
                return test_code

        # 获取模板
        template = matching_signature.emit_template
        if not template:
            return test_code

        # 应用模板生成布尔转换代码
        # __bool__ 的模板是 "!{self}.empty()"，表示"非空"
        # 所以我们直接使用这个模板
        code = template.replace("{self}", test_code)
        return code

    def _emit_raise(self, node: IRRaise, context: CodeGenContext) -> EmitResult:
        """生成 raise 语句代码

        raise 语句负责生成 throw 关键字，异常对象的构造由表达式发射器处理。

        处理：
        1. raise（无参数）：重新抛出当前异常 → throw; 或 goto __finally（在 finally 上下文中）
        2. raise ExceptionType（名称）：将其转换为无参构造调用
        3. raise <expression>：生成表达式并抛出 → throw <expression>; 或保存并 goto（在 finally 上下文中）

        注意：异常类型的特殊构造（如 MC_MAKE_EXCEPTION）由 ExceptionConstructorEmitter 处理。
        """
        # 检查是否在 exception handler（catch 块）内部
        in_exception_handler = self._is_in_exception_handler(node)

        # 检查是否有 finally 上下文
        finally_ctx = context.finally_stack.current()

        # 无参数 - 重新抛出当前异常
        if node.exc is None:
            if finally_ctx and in_exception_handler:
                # 在 catch 块中且有 finally：捕获当前异常并 goto
                code = f"{finally_ctx.exception_ptr_var} = std::current_exception();\n"
                code += f"goto {finally_ctx.label};"
                return EmitResult(code=code, precedence=0)
            else:
                # 在 try 块中或无 finally：正常 throw
                return EmitResult(code="throw;", precedence=0)

        generator = get_global_generator()

        # 特殊处理：如果是 IRName 且引用异常类型，转换为无参构造调用
        # 例如：raise ValueError -> raise ValueError()
        if isinstance(node.exc, IRName):
            # 检查是否是异常类型
            if context.current_node and self._is_exception_type_name(
                node.exc.id, context
            ):
                # 构造临时的 IRCall 节点（无参调用）
                call_node = IRCall(parent=node.exc.parent)
                call_node.func = node.exc
                call_node.args = []
                call_node.keywords = []
                # 使用 generator 生成代码，会自动调用 ExceptionConstructorEmitter
                exc_code = generator.generate_expression(call_node, context)

                if finally_ctx and in_exception_handler:
                    # 在 catch 块中且有 finally：保存异常并 goto
                    code = f"{finally_ctx.exception_ptr_var} = std::make_exception_ptr({exc_code});\n"
                    code += f"goto {finally_ctx.label};"
                    return EmitResult(code=code, precedence=0)
                else:
                    # 在 try 块中或无 finally：正常 throw
                    return EmitResult(code=f"throw {exc_code};", precedence=0)

        # 生成异常表达式
        exc_code = generator.generate_expression(node.exc, context)

        if finally_ctx and in_exception_handler:
            # 在 catch 块中且有 finally：保存异常并 goto
            code = f"{finally_ctx.exception_ptr_var} = std::make_exception_ptr({exc_code});\n"
            code += f"goto {finally_ctx.label};"
            return EmitResult(code=code, precedence=0)
        else:
            # 在 try 块中或无 finally：正常 throw
            return EmitResult(code=f"throw {exc_code};", precedence=0)

    def _is_in_exception_handler(self, node: IRNode) -> bool:
        """检查节点是否在 exception handler（catch 块）或 else 块内部

        由于IR结构中，raise语句的parent链是：
        IRRaise -> IRStmtBlock -> IRTryExcept（不经过IRExceptionHandler）

        所以需要特殊检查：找到包含raise的try-except，然后检查raise是否在其handler或orelse的body中。

        Args:
            node: 要检查的节点

        Returns:
            bool: 是否在 exception handler 或 else 块内部
        """
        from mcpy.ir.statements.exception import IRTryExcept, IRExceptionHandler
        from mcpy.ir.declarations.function import IRFunctionNode

        # 向上查找包含当前节点的 IRTryExcept
        current = node.parent
        while current is not None:
            if isinstance(current, IRTryExcept):
                # 检查 raise 是否在 try-except 的 handler 中
                for handler in current.handlers:
                    if handler.body and self._node_contains(handler.body, node):
                        return True

                # 检查 raise 是否在 else 块中
                if current.orelse and self._node_contains(current.orelse, node):
                    return True

                # 如果不在 handler 或 else 中，继续向上查找外层 try-except
            if isinstance(current, IRFunctionNode):
                return False
            current = current.parent
        return False

    def _node_contains(self, parent_node: IRNode, target_node: IRNode) -> bool:
        """检查parent_node是否包含target_node

        Args:
            parent_node: 父节点
            target_node: 目标节点

        Returns:
            bool: 是否包含
        """
        if parent_node == target_node:
            return True
        for child in parent_node.get_child_nodes():
            if self._node_contains(child, target_node):
                return True
        return False

    def _is_exception_type_name(self, name: str, context: CodeGenContext) -> bool:
        """检查名称是否引用异常类型（而不是异常变量）"""
        if not context.current_node:
            return False

        symbol = context.current_node.lookup_symbol(name)
        if not symbol or symbol.kind != SymbolKind.CLASS:
            return False

        return is_exception_type(symbol, context)

    def _emit_try_except(
        self, node: IRTryExcept, context: CodeGenContext
    ) -> EmitResult:
        """生成 try/except/finally 语句代码

        使用 goto 方案实现 Python finally 语义：
        - finally 代码只生成一次（放在 finally 标签处）
        - 所有退出点（return/break/continue/throw）都跳转到 finally
        - 零运行时开销，完整语义支持
        """
        context.require_include("mcpy/exception.h")

        # 如果有 finally，使用 goto 方案
        if node.finalbody:
            return self._emit_try_except_with_finally(node, context)

        # 没有 finally，使用原有简单实现
        lines = []

        # 处理 else 子句（需要在开头声明标志变量）
        no_exception_var = None
        if node.orelse:
            no_exception_var = self._get_next_no_exception_var_name(node)
            lines.append(f"bool {no_exception_var} = true;")

        # 生成 try 块
        try_body_lines = self._emit_try_block(node.body, context)
        lines.extend(try_body_lines)

        # 生成 except 子句
        if node.handlers:
            handler_lines = self._emit_except_handlers(
                node.handlers, no_exception_var, context
            )
            lines.extend(handler_lines)
        else:
            # 没有 except 子句，直接闭合 try 块
            lines.append("}")

        # 生成 else 子句
        if node.orelse and no_exception_var:
            else_lines = self._emit_else_clause(node.orelse, no_exception_var, context)
            lines.extend(else_lines)

        code = "\n".join(lines)
        return EmitResult(code=code, precedence=0)

    def _emit_try_block(self, body, context: CodeGenContext) -> list:
        """生成 try 块代码"""
        generator = get_global_generator()
        lines = ["try {"]

        if body:
            statements = self._get_statements(body)
            for stmt in statements:
                stmt_context = context.create_child_context(current_node=stmt)
                stmt_code = generator.generate_statement(stmt, stmt_context)
                if stmt_code:
                    lines.append(f"    {stmt_code}")

        return lines

    def _emit_except_handlers(
        self,
        handlers,
        no_exception_var: str | None,
        context: CodeGenContext,
    ) -> list:
        """生成所有 except 子句"""
        lines = []

        for handler in handlers:
            handler_lines = self._emit_single_handler(
                handler, no_exception_var, context
            )
            lines.extend(handler_lines)

        # 关闭所有 catch 块
        lines.append("}")

        return lines

    def _emit_single_handler(
        self, handler, no_exception_var: str | None, context: CodeGenContext
    ) -> list:
        """生成单个 except 子句"""
        generator = get_global_generator()
        lines = []

        exc_var_name = handler.exception_name if handler.exception_name else ""
        cpp_exception_type = self._get_exception_cpp_type(handler.type, context)

        # 生成 catch 声明
        if cpp_exception_type is None:
            # bare except: 捕获所有异常
            lines.append("} catch (...) {")
        else:
            # 特定异常类型
            lines.append(f"}} catch (const {cpp_exception_type}& {exc_var_name}) {{")

        # 重置 else 标志变量（表示有异常发生）
        if no_exception_var:
            lines.append(f"    {no_exception_var} = false;")

        # 生成异常处理代码块
        if handler.body:
            statements = self._get_statements(handler.body)
            for stmt in statements:
                stmt_context = context.create_child_context(current_node=stmt)
                stmt_code = generator.generate_statement(stmt, stmt_context)
                if stmt_code:
                    lines.append(f"    {stmt_code}")

        return lines

    def _get_exception_cpp_type(self, exc_type, context: CodeGenContext) -> str | None:
        """获取异常的 C++ 类型名称

        Returns:
            异常类型名称，或 None 表示 catch(...) 捕获所有异常
        """
        if exc_type is None:
            # except: 捕获所有异常 - 返回 None 表示使用 catch(...)
            return None

        # 提取异常类型名称
        exc_type_name = None
        if isinstance(exc_type, IRName):
            exc_type_name = exc_type.id
        elif isinstance(exc_type, IRAttribute):
            if isinstance(exc_type.value, IRName):
                exc_type_name = exc_type.attr

        # 查找异常类型的 C++ 映射
        if exc_type_name and context.current_node:
            symbol = context.current_node.lookup_symbol(exc_type_name)
            if symbol and symbol.type_config:
                cpp_type = symbol.type_config.get("cpp_type")
                if cpp_type:
                    # 添加必要的头文件
                    includes = symbol.type_config.get("includes", [])
                    for include in includes:
                        context.require_include(include)
                    return cpp_type

        # 默认使用通用异常类型
        return "mc::exception"

    def _emit_else_clause(
        self, orelse, no_exception_var: str, context: CodeGenContext
    ) -> list:
        """生成 else 子句（在没有异常时执行）"""
        generator = get_global_generator()
        lines = [f"if ({no_exception_var}) {{"]

        statements = self._get_statements(orelse)
        for stmt in statements:
            stmt_context = context.create_child_context(current_node=stmt)
            stmt_code = generator.generate_statement(stmt, stmt_context)
            if stmt_code:
                lines.append(f"    {stmt_code}")

        lines.append("}")
        return lines

    def _emit_finally_clause(self, finalbody, context: CodeGenContext) -> list:
        """生成 finally 子句

        简化实现：finally 代码直接放在 try/catch/else 之后

        限制：
        - 如果 try/catch/else 中有 return/throw/break/continue，finally 不会执行
        - 适用于简单的清理操作，不涉及提前退出的场景

        注意：由于 Python 函数作用域与 C++ 块作用域差异，以及 return 值覆盖等复杂语义，
        完整实现 Python finally 需要大量代码改写（复制 finally 代码到每个退出点）。
        当前简化实现适合大多数常见用例。
        """
        generator = get_global_generator()
        lines = []

        statements = self._get_statements(finalbody)
        for stmt in statements:
            stmt_context = context.create_child_context(current_node=stmt)
            stmt_code = generator.generate_statement(stmt, stmt_context)
            if stmt_code:
                lines.append(f"{stmt_code}")

        return lines

    def _emit_try_except_with_finally(
        self, node: IRTryExcept, context: CodeGenContext
    ) -> EmitResult:
        """使用 goto 方案生成 try/except/finally 代码

        生成代码结构：
        1. 创建并压入 finally 上下文到栈
        2. 声明控制变量（return 值、异常指针、break/continue 标志等）
        3. try/catch/else 块（所有提前退出都设置标志并 goto finally）
        4. finally 标签和代码
        5. 根据标志决定最终行为（return/rethrow/break/continue）
        6. 弹出 finally 上下文
        """
        context.require_include("mcpy/exception.h")
        context.require_include("<exception>")

        lines = []

        # 1. 生成 finally 标签名和后缀（需要唯一）
        finally_label = self._get_unique_finally_label(node)

        # 生成唯一的变量名后缀
        scope = node.get_parent_scope()
        counter = 1
        if scope:
            counter_key = "_finally_label_counter"
            counter = scope.get_extension_param(counter_key, 1)
        suffix = "" if counter == 1 else f"_{counter}"

        # 将后缀保存到节点
        node.set_extension_param("_finally_var_suffix", suffix)

        return_type = self._get_function_return_type(context)
        has_else = bool(node.orelse)
        in_loop = self._is_in_loop_context(node)

        # 2. 创建并压入 finally 上下文到栈
        finally_ctx = FinallyContext(
            label=finally_label,
            suffix=suffix,
            return_type=return_type,
            has_else=has_else,
            in_loop=in_loop,
        )
        context.finally_stack.push(finally_ctx)

        try:
            # 3. 声明控制变量
            control_vars = self._declare_finally_control_vars_from_context(finally_ctx)
            lines.extend(control_vars)

            # 4. 处理 else 子句（需要标志变量）
            no_exception_var = None
            if node.orelse:
                no_exception_var = self._get_next_no_exception_var_name(node)
                lines.append(f"bool {no_exception_var} = true;")

            # 5. 生成 try 块（带 goto）
            try_lines = self._emit_try_block_with_goto(node.body, finally_ctx, context)
            lines.extend(try_lines)

            # 6. 生成 except 子句（带 goto）
            if node.handlers:
                handler_lines = self._emit_except_handlers_with_goto(
                    node.handlers, no_exception_var, finally_ctx, context
                )
                lines.extend(handler_lines)
            else:
                # 没有 except 子句，需要捕获并保存异常
                lines.append("} catch (...) {")
                lines.append(
                    f"    {finally_ctx.exception_ptr_var} = std::current_exception();"
                )
                lines.append(f"    goto {finally_ctx.label};")
                lines.append("}")

            # 7. 生成 else 子句（带 goto）
            if node.orelse and no_exception_var:
                else_lines = self._emit_else_clause_with_goto(
                    node.orelse, no_exception_var, finally_ctx, context
                )
                lines.extend(else_lines)

            # 8. 生成 finally 标签
            lines.append("")  # 空行，确保标签单独一行
            lines.append(f"{finally_ctx.label}:")
            lines.append("{")  # 添加花括号防止 clang-format 把标签和语句放在同一行

            # 9. 弹出栈，这样 finally 块内部的 return/break/continue 就不会再 goto finally
            #    注意：这时外层 finally（如果有）仍然在栈中
            context.finally_stack.pop()

            # 10. 生成 finally 代码（此时栈已弹出，finally 内部的控制流语句是普通的）
            finally_body_lines = self._emit_finally_body(node.finalbody, context)
            for line in finally_body_lines:
                lines.append(f"    {line}")  # 缩进 finally 代码
            lines.append("}")  # 闭合花括号

            # 11. 生成退出处理逻辑（从栈获取外层信息）
            #     注意：这时 current 已经是外层了，outer 是外外层
            exit_lines = self._emit_finally_exit_handling_after_pop(
                finally_ctx, context
            )
            lines.extend(exit_lines)

            code = "\n".join(lines)
            return EmitResult(code=code, precedence=0)

        except Exception:
            # 出错时也要弹出栈
            if context.finally_stack.current() is finally_ctx:
                context.finally_stack.pop()
            raise

    def _get_unique_finally_label(self, node: IRTryExcept) -> str:
        """生成唯一的 finally 标签名"""
        scope = node.get_parent_scope()
        if scope is None:
            return "__finally"

        counter_key = "_finally_label_counter"
        counter = scope.get_extension_param(counter_key, 0)
        counter += 1
        scope.set_extension_param(counter_key, counter, replace_existing=True)

        if counter == 1:
            return "__finally"
        return f"__finally_{counter}"

    def _declare_finally_control_vars_from_context(
        self, finally_ctx: FinallyContext
    ) -> list:
        """从 finally 上下文声明控制变量"""
        lines = []

        # 异常指针（用于重新抛出异常）
        lines.append(f"std::exception_ptr {finally_ctx.exception_ptr_var} = nullptr;")

        # 检测是否在循环中
        if finally_ctx.in_loop:
            lines.append(f"bool {finally_ctx.should_break_var} = false;")
            lines.append(f"bool {finally_ctx.should_continue_var} = false;")

        # 返回值相关变量
        if finally_ctx.return_type and finally_ctx.return_type != "void":
            lines.append(f"bool {finally_ctx.has_return_var} = false;")
            # 使用默认初始化
            lines.append(
                f"{finally_ctx.return_type} {finally_ctx.return_value_var}{{}};"
            )
        elif finally_ctx.return_type == "void":
            lines.append(f"bool {finally_ctx.has_return_var} = false;")

        return lines

    def _is_in_loop_context(self, node: IRNode) -> bool:
        """检测节点是否在循环中"""
        from mcpy.ir.statements.control import IRForRange, IRForEach, IRWhile

        current = node.parent
        while current:
            if isinstance(current, (IRForRange, IRForEach, IRWhile)):
                return True
            current = current.parent
        return False

    def _get_function_return_type(self, context: CodeGenContext) -> str | None:
        """获取当前函数的返回类型"""
        from mcpy.ir.declarations.function import IRFunctionNode

        # 从 context 或当前节点向上查找函数定义
        current = context.current_node
        while current:
            if isinstance(current, IRFunctionNode):
                # 使用函数节点的 get_cpp_return_type 方法
                return_type = current.get_cpp_return_type()
                if return_type:
                    return return_type
                return "void"
            current = current.parent
        return None

    def _emit_try_block_with_goto(
        self, body, finally_ctx: FinallyContext, context: CodeGenContext
    ) -> list:
        """生成带 goto 的 try 块"""
        generator = get_global_generator()
        lines = ["try {"]

        has_control_flow = False
        if body:
            statements = self._get_statements(body)
            for i, stmt in enumerate(statements):
                stmt_context = context.create_child_context(current_node=stmt)
                stmt_code = generator.generate_statement(stmt, stmt_context)
                if stmt_code:
                    lines.append(f"    {stmt_code}")

                    # 检测最后一个语句是否是控制流语句（return/break/continue已转换为goto）
                    if i == len(statements) - 1 and "goto " in stmt_code:
                        has_control_flow = True

        return lines

    def _emit_except_handlers_with_goto(
        self,
        handlers,
        no_exception_var: str | None,
        finally_ctx: FinallyContext,
        context: CodeGenContext,
    ) -> list:
        """生成带 goto 的 except 子句"""
        lines = []

        # 检查是否已经有 bare except（捕获所有异常）
        has_bare_except = any(handler.type is None for handler in handlers)

        for handler in handlers:
            handler_lines = self._emit_single_handler_with_goto(
                handler, no_exception_var, finally_ctx, context
            )
            lines.extend(handler_lines)

        # 只在没有 bare except 时才自动添加 catch(...)
        # 因为用户的 bare except 已经生成了 catch(...)
        if not has_bare_except:
            # 未捕获的异常 - 必须捕获并保存，确保 finally 执行后重新抛出
            lines.append("} catch (...) {")
            lines.append(
                f"    {finally_ctx.exception_ptr_var} = std::current_exception();"
            )
            lines.append(f"    goto {finally_ctx.label};")
            lines.append("}")
        else:
            # 用户已有 bare except，只需闭合最后一个 catch 块
            lines.append("}")

        return lines

    def _emit_single_handler_with_goto(
        self,
        handler,
        no_exception_var: str | None,
        finally_ctx: FinallyContext,
        context: CodeGenContext,
    ) -> list:
        """生成单个带 goto 的 except 子句"""
        generator = get_global_generator()
        lines = []

        exc_var_name = handler.exception_name if handler.exception_name else ""
        cpp_exception_type = self._get_exception_cpp_type(handler.type, context)
        is_bare_except = cpp_exception_type is None

        # 生成 catch 声明
        if is_bare_except:
            # bare except: 捕获所有异常
            lines.append("} catch (...) {")
        else:
            # 特定异常类型
            lines.append(f"}} catch (const {cpp_exception_type}& {exc_var_name}) {{")

        # 重置 else 标志变量（表示有异常发生）
        if no_exception_var:
            lines.append(f"    {no_exception_var} = false;")

        # 生成异常处理代码块
        if handler.body:
            statements = self._get_statements(handler.body)
            for stmt in statements:
                stmt_context = context.create_child_context(current_node=stmt)
                stmt_code = generator.generate_statement(stmt, stmt_context)
                if stmt_code:
                    lines.append(f"    {stmt_code}")

        # bare except with finally 的特殊处理
        # 主动添加 goto 以确保标签被引用，避免 unused label 警告
        if is_bare_except:
            lines.append(f"    goto {finally_ctx.label};")
        # 其他 catch 块正常结束后会自然流到 try-catch 结构后，即 finally 标签
        # 不需要 goto（优化：减少不必要的跳转）

        return lines

    def _emit_else_clause_with_goto(
        self,
        orelse,
        no_exception_var: str,
        finally_ctx: FinallyContext,
        context: CodeGenContext,
    ) -> list:
        """生成带 goto 的 else 子句"""
        generator = get_global_generator()
        lines = []

        lines.append(f"if ({no_exception_var}) {{")

        has_control_flow = False
        statements = self._get_statements(orelse)
        for i, stmt in enumerate(statements):
            stmt_context = context.create_child_context(current_node=stmt)
            stmt_code = generator.generate_statement(stmt, stmt_context)
            if stmt_code:
                lines.append(f"    {stmt_code}")
                if i == len(statements) - 1 and "goto " in stmt_code:
                    has_control_flow = True

        # else 块正常结束后会自然流到 if 语句后，即 finally 标签
        # 不需要 goto（优化：减少不必要的跳转）
        lines.append("}")

        return lines

    def _emit_finally_body(self, finalbody, context: CodeGenContext) -> list:
        """生成 finally 代码块内容"""
        generator = get_global_generator()
        lines = []

        statements = self._get_statements(finalbody)
        for stmt in statements:
            stmt_context = context.create_child_context(current_node=stmt)
            stmt_code = generator.generate_statement(stmt, stmt_context)
            if stmt_code:
                # finally 代码不需要缩进（和函数体同级）
                lines.append(f"{stmt_code}")

        return lines

    def _emit_finally_exit_handling_after_pop(
        self, current_ctx: FinallyContext, context: CodeGenContext
    ) -> list:
        """在弹出栈后生成退出处理

        Args:
            current_ctx: 当前（已弹出）的 finally 上下文
            context: 代码生成上下文（栈中是外层 finally）
        """
        lines = []

        # 获取外层 finally 上下文（现在栈顶是外层）
        outer = context.finally_stack.current()

        # 1. 处理异常传递
        if outer:
            lines.append(f"if ({current_ctx.exception_ptr_var}) {{")
            lines.append(
                f"    {outer.exception_ptr_var} = {current_ctx.exception_ptr_var};"
            )
            lines.append(f"    goto {outer.label};")
            lines.append("}")
        else:
            lines.append(f"if ({current_ctx.exception_ptr_var}) {{")
            lines.append(
                f"    std::rethrow_exception({current_ctx.exception_ptr_var});"
            )
            lines.append("}")

        # 2. 处理 return 传递
        if current_ctx.return_type:
            if outer:
                lines.append(f"if ({current_ctx.has_return_var}) {{")
                lines.append(f"    {outer.has_return_var} = true;")
                if current_ctx.return_type != "void":
                    lines.append(
                        f"    {outer.return_value_var} = {current_ctx.return_value_var};"
                    )
                lines.append(f"    goto {outer.label};")
                lines.append("}")
            else:
                lines.append(f"if ({current_ctx.has_return_var}) {{")
                if current_ctx.return_type != "void":
                    lines.append(f"    return {current_ctx.return_value_var};")
                else:
                    lines.append("    return;")
                lines.append("}")

        # 3. 处理 break/continue（如果在循环中）
        if current_ctx.in_loop:
            if outer:
                lines.append(f"if ({current_ctx.should_break_var}) {{")
                lines.append(f"    {outer.should_break_var} = true;")
                lines.append(f"    goto {outer.label};")
                lines.append("}")
                lines.append(f"if ({current_ctx.should_continue_var}) {{")
                lines.append(f"    {outer.should_continue_var} = true;")
                lines.append(f"    goto {outer.label};")
                lines.append("}")
            else:
                lines.append(f"if ({current_ctx.should_break_var}) {{")
                lines.append("    break;")
                lines.append("}")
                lines.append(f"if ({current_ctx.should_continue_var}) {{")
                lines.append("    continue;")
                lines.append("}")

        return lines

    def _emit_nested_function(
        self, node: IRFunctionNode, context: CodeGenContext
    ) -> EmitResult:
        """处理嵌套函数定义

        关键：嵌套函数定义在 Python 中是赋值语句（函数是第一类值）
        def add(): ... 等价于 add = lambda: ...

        代码生成：
        1. 生成 struct 定义（添加到 extensions）
        2. 生成变量赋值代码（根据存储模式）
           - heap 模式：mc::variant add = mc::variant(mc::make_shared<functor>(...));
           - stack 模式：functor add(...);

        Args:
            node: 嵌套函数节点
            context: 代码生成上下文

        Returns:
            变量赋值代码的 EmitResult
        """
        from .nested_function_emitter import NestedFunctionEmitter

        # 判断是否是嵌套函数（在另一个函数内部定义）
        parent = node.parent
        is_nested = False
        while parent:
            if isinstance(parent, IRFunctionNode):
                is_nested = True
                break
            parent = parent.parent

        if is_nested:
            # 1. 生成 struct 定义（添加到 extension）
            NestedFunctionEmitter.generate_struct_if_needed(node, context)

            # 2. 检查是否是简单函数（无捕获）
            is_simple = node.get_extension_param("is_simple_non_capturing", False)
            if not is_simple:
                # 如果标记未设置，检查 captured_vars 是否为空
                captured_vars = node.captured_vars or []
                is_simple = len(captured_vars) == 0

            if is_simple:
                # 检查函数是否有默认参数
                has_default_params = False
                params = getattr(node, "params", [])
                if params:
                    for param in params:
                        if (
                            hasattr(param, "default_value")
                            and param.default_value is not None
                        ):
                            has_default_params = True
                            break

                if not has_default_params:
                    # 简单函数且没有默认参数：不生成变量声明，完全通过 call_emitter 在调用处生成临时对象调用
                    # 添加成功标记，告诉发射器系统这是预期的行为，不要继续尝试其他发射器
                    return EmitResult(code="", precedence=0, metadata={"success": True})
                # 如果有默认参数，继续后续逻辑，生成变量声明（因为需要 mcpy::call 调用）

            # 3. 生成变量赋值代码（函数定义 = 变量赋值）
            storage_mode = node.get_extension_param("storage_mode", "stack")
            from .nested_function.utils import get_functor_name

            functor_name = get_functor_name(node)
            func_var_name = node.name
            captured_vars = node.captured_vars or []  # 使用属性，默认为空列表

            if storage_mode == "heap":
                # 堆模式：mc::variant add = mc::variant(mc::make_shared<functor>(...));
                if captured_vars:
                    captures = ", ".join(captured_vars)
                    code = f"mc::variant {func_var_name} = mc::variant(mc::make_shared<{functor_name}>({captures}));"
                else:
                    code = f"mc::variant {func_var_name} = mc::variant(mc::make_shared<{functor_name}>());"
            else:
                # 栈模式：functor add(...);
                if captured_vars:
                    captures = ", ".join(captured_vars)
                    code = f"{functor_name} {func_var_name}({captures});"
                else:
                    code = f"{functor_name} {func_var_name};"

            return EmitResult(code=code, precedence=0)
        else:
            # 顶层函数，不应该由 StatementEmitter 处理
            return EmitResult(
                code=f"/* Top-level function {node.name} should not be handled by StatementEmitter */",
                precedence=0,
            )

    def get_priority(self) -> int:
        """语句发射器的优先级"""
        return 5  # 中等优先级
